﻿using DotNetWikiBot;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace Raspare
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
    public class WcfRaspare : IWcfRaspare
    {
        private MySqlDataEntities db;

        public Karaktär GetWikiSite(string value)
        {
            // Firstly make Site object, specifying site's URL and your bot account
            Site enWiki = new Site("http://wiki.raspare.se/api.php", ConfigurationManager.AppSettings["Username"], ConfigurationManager.AppSettings["Password"]);
            
            // Then make Page object, specifying site and page title in constructor
            Page p = new Page(enWiki, value);
            // Load actual page text from live wiki
            p.Load();
            
            var character = new Karaktär(p.title, p.text);

            return character;
        }

        public List<string> GetMyDekaederCharacterList(string name)
        {
            //var categories = new List<string>();
            ////categories.Add(name);
            ////categories.Add("Roller");
            //categories.Add("Dekaeder");

            //Site enWiki = new Site("http://wiki.raspare.se/api.php", ConfigurationManager.AppSettings["Username"], ConfigurationManager.AppSettings["Password"]);
            //PageList pl = new PageList(enWiki);
            //pl.FillFromCategoryTree(categories); 
            
            

            using (db = new MySqlDataEntities())
            {
                var personensAllaSidor = GetAllPagesInCategory(name);  
                var allaRoller = GetAllPagesInCategory("Roller");
                var allaDekaederSidor = GetAllPagesInCategory("Dekaeder");
                
                var snittet = personensAllaSidor.Intersect(allaRoller).Intersect(allaDekaederSidor).ToList();

                var list = new List<string>();
                foreach (var pageId in snittet)
                {
                    list.Add(db.mw_page.First(page => page.page_id == pageId).page_title.Replace("_", " "));
                }

                return list.OrderBy(s => s).ToList();
            }
        }

        private List<long> GetAllPagesInCategory(string category)
        {
            category = category.ToUpper().Replace(" ", "_");
            if (category.Contains("\n"))
            {
                category = category.Substring(category.IndexOf("\n", StringComparison.CurrentCultureIgnoreCase));
            }
            var list = new List<long>();
            list.AddRange(db.mw_categorylinkview.Where(cat => cat.cl_to.ToUpper().Equals(category, StringComparison.CurrentCultureIgnoreCase) && cat.cl_type.Equals("page")).Select(link => link.cl_from));
            var subcategories = db.mw_categorylinkview.Where(cat => cat.cl_to.ToUpper().Equals(category, StringComparison.CurrentCultureIgnoreCase) && cat.cl_type.Equals("subcat")).ToList().Select(link => link.cl_sortkey).ToList();
            foreach (var subcat in subcategories)
            {
                list.AddRange(GetAllPagesInCategory(subcat));
            }
            return list;
        }
        
        public List<string> GetMyList(List<string> categories)
        {
            Site enWiki = new Site("http://wiki.raspare.se/api.php", ConfigurationManager.AppSettings["Username"], ConfigurationManager.AppSettings["Password"]);
            PageList pl = new PageList(enWiki);
            pl.FillFromCategoryTree(categories);

            var list = pl.pages.Select(page => page.title).ToList();

            pl.Clear();

            pl.FillFromCategory("Roller");
            var secondlist = pl.pages.Select(page => page.title);

            var thirdlist = list.Where(l => secondlist.Contains(l)).ToList();

            return thirdlist;
        }

        public List<Kroklista> GetKrokar(string name)
        {
            var character = GetWikiSite(name);
            string kampanj = string.Empty;
            var completeList = new List<Kroklista>();
                    
            using (db = new MySqlDataEntities())
            {
                var listOfKampanjer = GetAllPagesInCategory("Kampanjer");
                var listOfKategorier = character.Kategorier.Select(kat => kat.Replace(" ", "_"));
                var stringKampanjer = db.mw_page.Where(page => listOfKampanjer.Contains(page.page_id) && listOfKategorier.Contains(page.page_title)).ToList();
                if (stringKampanjer.Any())
                {
                    kampanj = stringKampanjer.First().page_title;
                }
                
                if (!String.IsNullOrWhiteSpace(kampanj))
                {
                    var listOfKampanjPages = GetAllPagesInCategory(kampanj);
                    var listOfAllaRoller = GetAllPagesInCategory("Roller");
                    var listOfDödaRoller = GetAllPagesInCategory("Döda Roller");
                    var listOfRoller = listOfAllaRoller.Except(listOfDödaRoller);
                    var listOfRollerInKampanj = listOfKampanjPages.Intersect(listOfRoller);

                    foreach (var roll in listOfRollerInKampanj)
                    {
                        var extraCharacter = GetWikiSite(db.mw_page.First(page => page.page_id == roll).page_title);
                        completeList.Add(new Kroklista() { Namn = extraCharacter.Namn, Krokar = extraCharacter.Krokar });
                    }
                }
                else
                {
                    completeList.Add(new Kroklista() {Namn = character.Namn, Krokar = character.Krokar});
                }
            }
            return completeList;
        }
    }
}
